#include <iostream>
#include <memory>

using namespace std;

class Pancake {
public:
    virtual void Eat() const
    {
        std::cout << "Pancake Ate By Me." << std::endl;
    }
};

class ExtraEgg : public Pancake {
    std::unique_ptr<Pancake> pancake_ = nullptr;

public:
    ExtraEgg(std::unique_ptr<Pancake> &pancake)
        : pancake_(std::move(pancake))
    {
    }

    void Eat() const override
    {
        std::cout << "Extra Egg ";
        pancake_->Eat();
    }
};

class ExtraSausage : public Pancake {
    std::unique_ptr<Pancake> pancake_ = nullptr;

public:
    ExtraSausage(std::unique_ptr<Pancake> &pancake)
        : pancake_(std::move(pancake))
    {
    }

    void Eat() const override
    {
        std::cout << "Extra Sausage ";
        pancake_->Eat();
    }
};

void Eat(const Pancake &AtePancake)
{
    AtePancake.Eat();
}

std::unique_ptr<Pancake> GiveMeAPancake()
{
    std::unique_ptr<Pancake> pancake = std::make_unique<Pancake>();
    std::unique_ptr<Pancake> Sausage = std::make_unique<ExtraSausage>(pancake);
    std::unique_ptr<Pancake> Egg = std::make_unique<ExtraEgg>(Sausage);
    return std::move(Egg);
}

int main()
{
    auto pancake = GiveMeAPancake();
    Eat(*pancake); // Extra Egg Extra Sausage Pancake Ate By Me.
    return 0;
}
